home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctjmr86.arc / TJOS.ASM < prev   
Assembly Source File  |  1985-12-13  |  5KB  |  223 lines

  1. ; File:  tjos.asm
  2. ; Auth:  Richard Foard
  3.  
  4.  
  5.     TITLE   tjos
  6. ;
  7. ; Routines in this module (Microsoft C subroutine linkage):
  8. ;
  9. ;
  10. ; init_os()
  11. ;
  12. ;    Prepares TJ/OS environment for use.  Upon exit, caller is running
  13. ;    as first task.
  14. ;
  15. ;
  16. ; int fork(stack, stack_size)
  17. ;     char    *stack;
  18. ;     int    stack_size;
  19. ;
  20. ;    Creates and activates a task.  Returns 'false' to the calling task and
  21. ;    'true' to the newly created task.
  22. ;
  23. ;
  24. ; yield()
  25. ;
  26. ;    Allows a context switch to occur.
  27. ;
  28. ;
  29. ; wait(event_counter)
  30. ;     int    *event_counter;
  31. ;
  32. ;    Waits for an event.
  33. ;
  34. ;
  35. ; post(event_counter)
  36. ;     int    *event_counter;
  37. ;
  38. ;    Signals that an event has occurred.
  39. ;
  40. ;
  41. ; stop()
  42. ;
  43. ;    Deactivates and destroys the calling task.
  44. ;
  45.  
  46. _TEXT    SEGMENT  BYTE PUBLIC 'CODE'
  47. _TEXT    ENDS
  48.  
  49. CONST    SEGMENT  WORD PUBLIC 'CONST'
  50. CONST    ENDS
  51.  
  52. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  53. _BSS    ENDS
  54.  
  55. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  56. _DATA    ENDS
  57.  
  58. DGROUP    GROUP    CONST,    _BSS,    _DATA
  59.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
  60.  
  61. PUBLIC        _init_os
  62. PUBLIC        _yield
  63. PUBLIC        _fork
  64. PUBLIC        _wait
  65. PUBLIC        _post
  66. PUBLIC        _stop
  67. PUBLIC        __chkstk
  68.  
  69. _TEXT        SEGMENT
  70. EXTRN        _exit:NEAR
  71. _TEXT        ENDS
  72.  
  73. _BSS        SEGMENT
  74. max_tasks    equ    8
  75. ct_limit    equ    max_tasks * 2
  76. task_tbl    dw    max_tasks dup (0)
  77. cur_task    dw    0
  78. actv_tasks    dw    0
  79.         EVEN
  80. _BSS        ENDS
  81.  
  82. ;---------------------------------------------------------------------------
  83. _TEXT        SEGMENT
  84.  
  85. ;-------------------------
  86. _init_os    PROC NEAR        ;init_os() {
  87.     mov    cur_task,0        ; cur_task = 0;
  88.     mov    actv_tasks,1        ; actv_tasks = 1;
  89.     sub    ax,ax            ; task_tbl[0..max_tasks - 1] = 0;
  90.     mov    cx,max_tasks        ;
  91.     mov    bx,offset task_tbl    ;
  92. ini_1:                    ;
  93.     mov    [bx],ax            ;
  94.     add    bx,2            ;
  95.     dec    cx            ;
  96.     jnz    ini_1            ;
  97.     ret                ;
  98. _init_os    ENDP            ;}
  99.  
  100. ;-------------------------
  101. _yield        PROC NEAR        ;yield()
  102.     push    bp            ; (preserve BP)
  103.     mov    bx,offset task_tbl    ; task_tbl[cur_task] = SP;
  104.     mov    ax,cur_task        ;
  105.     add    bx,ax            ;
  106.     mov    [bx],sp            ;
  107. yie_0:                    ;
  108.     add    ax,2            ; do {
  109.     cmp    ax,ct_limit        ;   cur_task = (cur_task + 2)
  110.     jne    yie_1            ;            % ct_limit;
  111.     sub    ax,ax            ;
  112. yie_1:                    ;
  113.     mov    bx,offset task_tbl    ; } while (task_tbl[cur_task] == 0);
  114.     add    bx,ax            ;
  115.     push    ax            ;
  116.     mov    ax,[bx]            ;
  117.     or    ax,ax            ;
  118.     pop    ax            ;
  119.     jnz    yie_2            ;
  120.     jmp    yie_0            ;
  121. yie_2:                    ;
  122.     mov    bx,offset task_tbl    ; SP = task_tbl[cur_task];
  123.     mov    cur_task,ax        ;
  124.     add    bx,ax            ;
  125.     mov    sp,[bx]            ;
  126.     pop    bp            ; (restore BP)
  127.     mov    ax,1            ; return(1);
  128.     ret                ;}
  129. _yield        ENDP
  130.  
  131. ;-------------------------
  132. _fork        PROC NEAR        ;int fork(stack, stack_size) {
  133.     mov    ax,actv_tasks        ; if (actv_tasks == max_tasks)
  134.     cmp    ax,max_tasks        ;   exit(1);
  135.     jne    for_0            ;
  136.     mov    ax,1            ;
  137.     push    ax            ;
  138.     call    _exit            ;
  139. for_0:                    ;
  140.     inc    ax            ; actv_tasks = actv_tasks + 1;
  141.     mov    actv_tasks,ax        ;
  142.     pop    dx            ; (caller's return addr)
  143.     pop    ax            ; (new task stack base)
  144.     pop    bx            ; (new task stack size)
  145.     push    bx            ; (restore caller's stack)
  146.     push    ax            ;
  147.     push    dx            ;
  148.     push    bp            ; (preserve caller's BP)
  149.     mov    bp,sp            ; (and caller's SP)
  150.     add    ax,bx            ; (establish new task's base sp)
  151.     sub    ax,4            ; (allow pop of fork's parameters)
  152.     mov    sp,ax            ;
  153.     push    dx            ; (new task return addr)
  154.     push    ax            ; (and bp register image)
  155.     mov    bx,offset task_tbl    ; (find free slot in task_tbl)
  156. for_1:    mov    ax,[bx]            ;
  157.     or    ax,ax            ;
  158.     jz    for_2            ;
  159.     add    bx,2            ;
  160.     jmp    for_1            ;
  161. for_2:    mov    [bx],sp            ; (install new task in task_tbl)
  162.     mov    sp,bp            ; (restore caller's stack)
  163.     pop    bp            ; (and BP)
  164.     sub    ax,ax            ; return (0);
  165.     ret                ;}
  166. _fork        ENDP
  167.  
  168. ;-------------------------
  169. _wait        PROC NEAR        ;wait(event_counter) {
  170. wai_0:    pop    cx            ;
  171.     pop    bx            ;
  172.     push    bx            ;
  173.     push    cx            ;
  174.     cli                ; (protect test-and-set)
  175.     mov    ax,[bx]            ;
  176.     or    ax,ax            ; 
  177.     jnz    wai_1            ; while (*event_counter == 0)
  178.     sti                ;
  179.     call    _yield            ;   yield();
  180.     jmp    wai_0            ;
  181. wai_1:    dec    ax            ; --(*event_counter);
  182.     mov    [bx],ax            ;
  183.     sti                ;
  184.     ret                ;}
  185. _wait        ENDP            ;
  186.  
  187. ;-------------------------
  188. _post        PROC NEAR        ;post(event_counter) {
  189.     pop    cx            ;
  190.     pop    bx            ;
  191.     push    bx            ;
  192.     inc    word ptr [bx]        ; ++(*event_counter);
  193.     jmp    cx            ;
  194. _post        ENDP            ;}
  195.  
  196. ;-------------------------
  197. _stop        PROC NEAR        ;stop() {
  198.     mov    ax,actv_tasks        ; if (--actv_tasks == 0) exit(0);
  199.     dec    ax            ;
  200.     jnz    sto_0            ;
  201.     sub    ax,ax            ;
  202.     push    ax            ;
  203.     call    _exit            ;
  204. sto_0:                    ;
  205.     mov    actv_tasks,ax        ;
  206.     mov    bx,offset task_tbl    ;
  207.     mov    ax,cur_task        ;
  208.     add    bx,ax            ; task_tbl[cur_task] = 0;
  209.     mov    word ptr [bx],0        ; (join 'yield' to switch context)
  210.     jmp    yie_0            ;}
  211. _stop        ENDP
  212.  
  213. ;-------------------------
  214. __chkstk:                ;chkstk:
  215.     pop    cx            ; (allocate AX bytes of stack space)
  216.     mov    bx,sp            ;
  217.     sub    bx,ax            ;
  218.     mov    sp,bx            ;
  219.     jmp    cx            ;
  220.  
  221. _TEXT    ENDS
  222. END
  223.